import { login, logout, getInfo } from '@/api/user'
import { getToken, setToken, removeToken } from '@/utils/auth'
import router, { resetRouter } from '@/router'
import { allAsyncRoutes, constantRoutes, anyRoute } from '@/router/routes'
import cloneDeep from 'lodash/cloneDeep'//解决切换用户只能看到部分路由

function filterAsyncRoutes(allAsyncRoutes, routeNames) {
  return allAsyncRoutes.filter(route => {
    if (routeNames.indexOf(route.name) === -1) return false
    if (route.children && route.children.length > 0) {
      route.children = filterAsyncRoutes(route.children, routeNames)
    }
    return true
  })
}

const getDefaultState = () => {
  return {
    token: getToken(),
    name: '', // 用户名
    avatar: '', // 头像url
    roles: [], // 角色列表
    buttons: [], // 按钮权限列表
    routes: [] // 路由权限列表
  }
}

const state = getDefaultState()

const mutations = {
  RESET_STATE: (state) => {
    Object.assign(state, getDefaultState())
  },
  SET_TOKEN: (state, token) => {
    state.token = token
  },
  SET_NAME: (state, name) => {
    state.name = name
  },
  SET_AVATAR: (state, avatar) => {
    state.avatar = avatar
  },

  // 保存用户及权限相关数据
  SET_USER(state, { name, avatar, roles, buttons, asyncRoutes }) {
    state.name = name
    state.avatar = avatar
    state.roles = roles
    state.buttons = buttons
    // 常量路由和异步路由
    state.routes = constantRoutes.concat(asyncRoutes)
  }
}

const actions = {
  // 登录异步action
  login({ commit }, userInfo) {
    const { username, password } = userInfo
    return new Promise((resolve, reject) => {
      login({ username: username.trim(), password: password }).then(response => {
        const { data } = response
        commit('SET_TOKEN', data.token)
        setToken(data.token)
        resolve()
      }).catch(error => {
        reject(error)
      })
    })
  },

  // 获取用户信息的异步action
  async getInfo({ commit }) {
    // 获取用户信息和权限数据
    const result = await getInfo()
    const { name, avatar, roles, buttons, routes } = result.data
    // 根据routes对allAsyncRoutes进行过滤生成用户权限路由列表
    const asyncRoutes = filterAsyncRoutes(cloneDeep(allAsyncRoutes), routes)
    // 动态注册权限路由和通配路由
    router.addRoutes([...asyncRoutes, anyRoute])
    // 保存用户及权限数据
    commit('SET_USER', { name, avatar, roles, buttons, asyncRoutes })
  },

  // 退出登陆的异步action
  logout({ commit }) {
    return new Promise((resolve, reject) => {
      logout().then(() => {
        removeToken() // must remove  token  first
        resetRouter()
        commit('RESET_STATE')
        resolve()
      }).catch(error => {
        reject(error)
      })
    })
  },

  /* 
  重置token和用户信息的同步action
  */
  resetToken({ commit }) {
    return new Promise(resolve => {
      removeToken() // must remove  token  first
      commit('RESET_STATE')
      resolve()
    })
  }
}

export default {
  namespaced: true,
  state,
  mutations,
  actions
}

